package cn.itsource.crm.web.aop;

import cn.itsource.crm.domain.Employee;
import cn.itsource.crm.domain.SystemLog;
import cn.itsource.crm.service.ISystemLogService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Aspect
@Component
public class SystemLogAspect {
    //@Autowired
    //private  SystemLogService loginfoService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISystemLogService systemLogService;

    //private static final Logger logger = LoggerFactory.getLogger(ArchivesLog.class);
 
    /*@Pointcut("@annotation(ArchivesLog)")
    public void controllerAspect() {
        //System.out.println("切入点...");
    }*/

    private Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);


    @Pointcut("execution(* cn.itsource.crm.web.controller.*.*(..))")
    public void method(){
    }

   /* @After("method()")
    public void after(JoinPoint joinPoint){
        System.err.println("this is after.................");
    }*/


    /**
     * 方法调用后触发 , 记录正常操作
     * 
     * @param joinPoint
     * @throws ClassNotFoundException 
     */
    @AfterReturning("method()")
    public  void afterReturning(JoinPoint joinPoint) throws ClassNotFoundException {
        //访问时间
        Date startTime =new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        String opTime = sdf.format(startTime);

        // 获取用户IP
        String ip = request.getRemoteAddr();
        //获取用户名
        String username = getEmployeeMsg().getUsername();
        // 控制器名
        //String targetName = getMethodDesc(joinPoint).getController();
        // 方法名
        String methodName = getMethodDesc(joinPoint).getFunction();
        //参数
        String params = getMethodDesc(joinPoint).getParams();
        // 操作说明
        //String operteContent = getMethodDesc(joinPoint).getOperateContent();
        //创建日志对象
        SystemLog systemLog = new SystemLog();
        //设置用户
        systemLog.setOpUser(username);
        //设置操作时间
        systemLog.setOpTime(opTime);
        //设置ip
        systemLog.setOpIp(ip);
        //调用的方法
        systemLog.setFunction(methodName);
        //参数信息
        systemLog.setParams(params);

//        systemLog.setOperateContent(operteContent);
//        systemLog.setController(targetName);

        //将日志信息保存到数据库
        System.out.println("执行-------------------将日志信息保存到数据库");
        System.out.println("日志信息:"+systemLog);
        systemLogService.save(systemLog);
    }
 
    /**
     *  发生异常，走此方法
     * @param joinPoint
     * @param e
     */
    /*@AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void AfterThrowing(JoinPoint joinPoint, Throwable e) {
        try {
            // 用户IP
            String ip = getEmployeeMsg().getLoginIp();
            // 控制器名
            String targetName = getMethodDesc(joinPoint).getController();
            // 方法名
            String methodName = getMethodDesc(joinPoint).getMethod();
            // 操作说明
            //String operteContent = getMethodDesc(joinPoint).getOperateContent();
            SystemLog systemLog = new SystemLog();
            String exMsg = e.getCause().toString();
            if (exMsg != null) {
                int type = 2;
                systemLog.setEmployeeId(employeeId);
                systemLog.setIp(ip);
                //systemLog.setOperateContent(operteContent);
                systemLog.setMethod(methodName);
                systemLog.setController(targetName);
                systemLog.setType(type);
                systemLog.setExMsg(exMsg);
                loginfoService.insertLog(systemLog);
            }
        } catch (Exception e1) {
            logger.error(e1.getMessage());
        }
    }*/
 
    /**
     * 获取 注解中对方法的描述
     * 
     * @return
     * @throws ClassNotFoundException
     */
    public static SystemLog getMethodDesc(JoinPoint joinPoint) throws ClassNotFoundException {
        //控制器名
        String targetName = joinPoint.getTarget().getClass().getName();
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取参数，并且去掉方法参数的servlet对象
        Object[] arguments = joinPoint.getArgs();
        Object[] arguments2 = removeServletObjects(arguments);
        /*for (Object o : arguments2) {
            System.out.println("---------------------------------参数---"+o);
        }*/
        //获取方法信息描述
        /*Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String operteContent = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
　　　　　　　　　　　　// 操作说明
                    operteContent = method.getAnnotation(ArchivesLog.class).operteContent();
                    break;
                }
            }
        }*/
        SystemLog systemLog = new SystemLog();
        //systemLog.setController(targetName);
        systemLog.setFunction(methodName);
        systemLog.setParams(Arrays.toString(arguments2));
        //systemLog.set(operteContent);
        return systemLog;
    }
 
    /**
     * 得到用户信息
     * 
     * @return
     */
    public static Employee getEmployeeMsg() {
        Subject subject = SecurityUtils.getSubject();
        return (Employee)subject.getPrincipal();
    }

    /*去掉方法参数的servlet对象*/
    public static Object[] removeServletObjects(Object[] objects) {
        List list = Arrays.asList(objects);
        list = new ArrayList(list);
        for (int i = 0; i < list.size(); i++) {
            Object object = list.get(i);
            if (object instanceof HttpServletResponse || object instanceof HttpServletRequest) {
                list.remove(object);
                i--;
            }
        }
        System.out.println(list);
        objects = list.toArray();
        return objects;
    }

}